package cn.flkj.lucia2a2.intermediate;


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.StringUtils;
import org.hyperledger.fabric.protos.peer.Query;
import org.hyperledger.fabric.sdk.Peer;
import org.hyperledger.fabric.sdk.User;
import org.hyperledger.fabric.sdk.exception.ChaincodeEndorsementPolicyParseException;
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric.sdk.exception.ProposalException;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * @author : 州长在手 2021/1/5 下午2:17
 */
public class FabricManager {
    private IntermediateOrg org;

    FabricManager(IntermediateOrg org) {
        this.org = org;
    }

    public IntermediateOrg getOrg() {
        return org;
    }

    public void setUser(String leagueName, String orgName, String peerName, String username, String skPath, String certificatePath) throws InvalidArgumentException {
        if (StringUtils.equals(username, org.getUsername())) {
            return;
        }
        User user = org.getUser(username);
        if (null == user) {
            IntermediateUser intermediateUser = new IntermediateUser(leagueName, orgName, peerName, username, skPath, certificatePath);
            org.setUsername(username);
            org.addUser(leagueName, orgName, peerName, intermediateUser, org.getFabricStore());
        }
        org.getClient().setUserContext(org.getUser(username));
    }

    //从channel获得peer节点信息
    public Collection<Peer> queryPeer() {
        return org.getChannel().get().getPeers();
    }

    public List<Query.ChaincodeInfo> queryInstantiatedChaincodes(Peer peer) throws InvalidArgumentException, ProposalException {
        return org.getChannel().get().queryInstantiatedChaincodes(peer);

    }


    public List<Query.ChaincodeInfo> queryInstantiated(Peer peer) throws InvalidArgumentException, ProposalException {
        return org.getChannel().queryInstantiated(peer);
    }


    /**
     * 安装智能合约
     *
     */
    public JSONObject lifecycleChaincodeInstall(
            String chaincodeName,
            String chaincodeVersion,
            String chaincodeLabel, // 标签，是名字加版本号的结合
            String chaincodeSourceLocation, // GOPATH
            String chaincodePath, // 相对于GOPATH的路径
            String metadadataSource, // metadadataSource,一般是couchdb的连接方式JSON的路径
            String chaincodeEndorsementPolicyPath // 策略文件
    ) throws Exception {
        IntermediateLifecycleChaincode ic = new IntermediateLifecycleChaincode(
                chaincodeName,
                chaincodeVersion,
                chaincodeLabel,
                chaincodeSourceLocation,
                chaincodePath,
                metadadataSource,
                chaincodeEndorsementPolicyPath,
                null);
        String pkid = null;
        try {
             pkid = ic.install(org);
        }catch (Exception e){
            System.out.println("Install code >>> "+ e.getMessage());
        }
        return JSONObject.parseObject( "{ "+ "\"package_id\":"+"\""+ pkid+"\"}") ;
    }

    /**
     * 审批链码
     */
    public JSONObject lifecycleChaincodeApproveformyorg( String chaincodeName,
                                                         String chaincodeVersion,
                                                         String packageid) {
        IntermediateLifecycleChaincode ic = new IntermediateLifecycleChaincode(chaincodeName,chaincodeVersion,packageid);
        try {
            ic.approveformyorg(org);
        }catch (Exception e){
            System.out.println("Approveformyorg code >>> "+ e.getMessage());
        }
        return new JSONObject();
    }


    /**
     * 提交智能合约
     */

    public JSONObject lifecycleChaincodeCommit( String chaincodeName,
                                                String chaincodeVersion,
                                                String packageid) {
        IntermediateLifecycleChaincode ic = new IntermediateLifecycleChaincode(chaincodeName,chaincodeVersion,packageid);
        try {
            ic.commit(org);
        }catch (Exception e){
            System.out.println("commit code >>> "+ e.getMessage());
        }
        return new JSONObject();
    }
//    public JSONObject instantiate(String chaincodeName, String[] args) throws InvalidArgumentException, ProposalException, IOException, ChaincodeEndorsementPolicyParseException {
//        return org.getChainCode(chaincodeName).instantiate(org, args);
//    }

    /**
     * 升级智能合约
     *
     * @param chaincodeName 智能合约名
     * @param args          初始化参数数组
     */
//    public JSONObject upgrade(String chaincodeName, String[] args) throws InvalidArgumentException, ProposalException, IOException, ChaincodeEndorsementPolicyParseException {
//
//        return org.getChainCode(chaincodeName).upgrade(org, args);
//    }

    /**
     * 智能合约执行
     *
     * @param chaincodeName 智能合约名
     * @param fcn           方法名
     * @param args          参数数组
     */

    public JSONObject invoke(String chaincodeName, String fcn, String[] args) throws InvalidArgumentException, ProposalException, IOException {

        return org.getChainCode(chaincodeName).invoke(org, fcn, args);
    }

    /**
     * 智能合约查询
     *
     * @param chaincodeName 智能合约名
     * @param fcn           方法名
     * @param args          参数数组
     */
    public JSONObject query(String chaincodeName, String fcn, String[] args) throws InvalidArgumentException, ProposalException {
        return org.getChainCode(chaincodeName).query(org, fcn, args);

    }

    /**
     * 在指定频道内根据transactionID查询区块
     *
     * @param txID transactionID
     */
    public JSONObject queryBlockByTransactionID(String txID) throws InvalidArgumentException, ProposalException, IOException {

        return org.getChannel().queryBlockByTransactionID(txID);

    }

    /**
     * 在指定频道内根据hash查询区块
     *
     * @param blockHash hash
     */
    public JSONObject queryBlockByHash(byte[] blockHash) throws InvalidArgumentException, ProposalException, IOException {

        return org.getChannel().queryBlockByHash(blockHash);

    }

    /**
     * 在指定频道内根据区块高度查询区块
     *
     * @param blockNumber 区块高度
     */
    public JSONObject queryBlockByNumber(long blockNumber) throws InvalidArgumentException, ProposalException, IOException {
        return org.getChannel().queryBlockByNumber(blockNumber);

    }

    /**
     * Peer加入频道
     *
     * @param peerName             当前指定的组织节点域名
     * @param peerLocation         当前指定的组织节点访问地址
     * @param peerEventHubLocation 当前指定的组织节点事件监听访问地址
     */
//    public JSONObject joinPeer(String peerName, String peerLocation, String peerEventHubLocation, String serverCrtPath, String clientCertPath, String clientKeyPath) throws InvalidArgumentException ,ProposalException {
//            return org.getChannel().joinPeer(new IntermediatePeer(peerName, peerLocation, peerEventHubLocation, serverCrtPath, clientCertPath, clientKeyPath));
//    }

    /**
     * 查询当前频道的链信息，包括链长度、当前最新区块hash以及当前最新区块的上一区块hash
     */
    public JSONObject getBlockchainInfo() throws InvalidArgumentException, ProposalException {
        return org.getChannel().getBlockchainInfo();
    }
}
